package com.bwstudio.common.autoidempotent.service;

import com.bwstudio.common.autoidempotent.config.AutoIdempotentProperties;
import com.bwstudio.common.autoidempotent.constant.Constant;
import com.bwstudio.common.autoidempotent.exception.AutoIdempotentException;
import com.bwstudio.common.autoidempotent.exception.AutoIdempotentErrorCodeIEnum;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;

/**
 * @author buwei
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class TokenServiceImpl implements TokenService {

    private final RedisService redisService;

    private final AutoIdempotentProperties autoIdempotentProperties;

    /**
     * 创建token
     *
     * @return
     */
    @Override
    public String createToken() {
        String str = UUID.randomUUID()
                .toString()
                .replace("-", "")
                .toUpperCase();
        StringBuilder token = new StringBuilder();
        try {
            token.append(Constant.REDIS_TOKEN_PREFIX).append("_").append(str);
            redisService.setEx(token.toString(), token.toString(),autoIdempotentProperties.getTokenExpireTimeInMs());
            boolean notEmpty = StringUtils.isNotEmpty(token.toString());
            if (notEmpty) {
                return token.toString();
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 检验token
     *
     * @param request
     * @return
     */
    @Override
    public boolean checkToken(HttpServletRequest request) throws Exception {
        String token = request.getHeader(Constant.AUTO_IDEMPOTENT_TOKEN_NAME);
        // header中不存在token
        if (StringUtils.isBlank(token)) {
            token = request.getParameter(Constant.AUTO_IDEMPOTENT_TOKEN_NAME);
            // parameter中也不存在token
            if (StringUtils.isBlank(token)) {
                throw new AutoIdempotentException(AutoIdempotentErrorCodeIEnum.IDEMPOTENT_TOKEN_NOT_FOUND);
            }
        }

        if (!redisService.exists(token)) {
            throw new AutoIdempotentException(AutoIdempotentErrorCodeIEnum.REPETITIVE_OPERATION);
        }

        boolean remove = redisService.remove(token);
        if (!remove) {
            throw new AutoIdempotentException(AutoIdempotentErrorCodeIEnum.REPETITIVE_OPERATION);
        }
        return true;
    }
}
